<script setup lang="ts">
import HandsonTable from 'handsontable'
import { registerAllModules } from 'handsontable/registry'
import 'handsontable/styles/handsontable.css'
import 'handsontable/styles/ht-theme-main.css'
import '@/style/handsontable-theme.css'
import { registerLanguageDictionary, zhCN } from 'handsontable/i18n'
import { HyperFormula } from 'hyperformula'
import { REPORT_FORM_ID, REPORT_ID } from '@/enum'
import useReportDetail, { type LoadReportResponse } from '../useReportDetail'
import type { SaveFnParams, SaveParams } from '../type'
import { saveReportDataOfCompanyPrimaryElectricityDevice, updateReportDataOfCompanyPrimaryElectricityDevice } from '@/api/modules/dataReport'
import useTheme from '../useTheme'
import { READONLY_CELL_CLASS, ROUND_NUMBER } from '../config'
import useValidate from '../useValidate'
import useHotUnmount from '../useHotUnmount'
import useSubmitForTab from '../useSubmitForTab'

defineOptions({ name: 'CompanyPrimaryElectricityDevice1' })
const props = defineProps<{
  socialCreditCode: string
  company: string
  readonly?: boolean
  /** 加载远程数据时使用的ID */
  dataId?: number
}>()

registerLanguageDictionary(zhCN)

// register Handsontable's modules
registerAllModules()

const HEADERS = [
  ['主通风机', null, null, null, null, null, null],
  [
    '装机容量（kw）',
    '起码',
    '止码',
    '通风系统耗电量（千瓦时）',
    '实际总风量（立方米）',
    '平均全压（帕）',
    '工序能耗',
  ],
]
const FOOTERS = [
  [
    '备注',
    '主要通风系统工序能耗指标等级：能耗值【KWH/(Mm3.pa)】轴流式  一级≤0.36；二级0.361-0.40；三级0.401-0.55',
    null,
    null,
    null,
    null,
    null,
  ],
]
const DEFAULT_MERGE_CELLS = [
  { row: 0, col: 0, rowspan: 1, colspan: 7 },
]
const KEYS = ['installedCapacity', 'startQuantity', 'endQuantity', 'electricQuantity']

const wrapper = ref<HTMLElement>()
const hot = ref<HandsonTable>()
// 主通风机
const formId = ref(REPORT_FORM_ID.MAIN_VENTILATOR)
const loadReportResponse = shallowRef<LoadReportResponse>()
const { getReportDataById, beforeChangeHook } = useReportDetail()
const {
  submitForTab: _submitForTab,
  generateHash,
  checkHash,
} = useSubmitForTab(() => hot.value)

async function loadData() {
  if (props.dataId) {
    const data = await getReportDataById(props.dataId, unref(formId))
    loadReportResponse.value = data
    // 如果远程没有数据，则保留初始化的状态，不执行loadData
    if (data.webReportData) {
      try {
        const dataList = JSON.parse(data.webReportData) as any[]
        hot.value?.loadData(dataList)
      }
      catch (e) {
        console.error(e)
        ElMessage.error('[webReportData]数据解析错误')
      }
    }
  }
}

function updateFormulas() {
  if (hot.value) {
    const r = hot.value.countRows()
    // 工序能耗公式
    const formula = `=IFERROR(ROUND((SUM(D3:D${r - 1}))/E3/F3*1000000,${ROUND_NUMBER}),"")`
    hot.value.setSourceDataAtCell(2, 6, formula)
  }
}

function updateMergeCells() {
  if (hot.value) {
    // 总行数减去3行后都是数据集合行
    const r = hot.value.countRows() - 3

    hot.value.updateSettings({
      mergeCells: [
        // 头部
        ...DEFAULT_MERGE_CELLS,
        // 数据行
        { row: 2, col: 4, rowspan: r, colspan: 1 },
        { row: 2, col: 5, rowspan: r, colspan: 1 },
        { row: 2, col: 6, rowspan: r, colspan: 1 },
        // 最后一行
        { row: r + 2, col: 1, rowspan: 1, colspan: 6 },
      ],
    })
  }
}

function updateReadonly() {
  if (hot.value) {
    const r = hot.value.countRows()
    hot.value.updateSettings({
      cell: [
        { row: 2, col: 6, readOnly: true },
        { row: r - 1, col: 1, className: 'htLeft' },
      ],
      cells: (row: number, col: number) => {
        // 从第三行到倒数第二行都可以编辑
        // 工序能耗单元格只读
        return row >= 2 && row < r - 1 && !props.readonly && col !== 6
          ? { readOnly: false, type: col !== 0 ? 'numeric' : 'text' }
          : {}
      },
    })
  }
}

async function init() {
  if (!wrapper.value)
    return
  hot.value = new HandsonTable(wrapper.value, {
    selectionMode: 'single',
    readOnly: true,
    // disableVisualSelection: props.readonly,
    language: zhCN.languageCode,
    data: [
      ...HEADERS,
      ['', '', '', '', '', '', ''],
      ['', '', '', '', null, null, null],
      ['', '', '', '', null, null, null],
      ...FOOTERS,
    ],
    formulas: {
      engine: HyperFormula,
    },
    className: 'htCenter htMiddle',
    readOnlyCellClassName: READONLY_CELL_CLASS,
    stretchH: 'all',
    colWidths: 100,
    manualColumnResize: true,
    colHeaders: true,
    rowHeaders: true,
    contextMenu: props.readonly
      ? false
      : {
          items: {
            row_above: {
              disabled() {
                // insert row above 只能在第3行至最后一行之间（含）
                const r1 = 2
                const r2 = this.countRows() - 1
                const [startRow] = this.getSelectedLast() ?? []
                if (startRow) {
                  return startRow < r1 || startRow > r2
                }
                return true
              },
            },
            row_below: {
              disabled() {
                // “insert row below”只能在第2行至倒数第二行之间（含）
                const r1 = 1
                const r2 = this.countRows() - 1
                const [startRow] = this.getSelectedLast() ?? []
                if (startRow) {
                  return startRow < r1 || startRow >= r2
                }
                return true
              },
            },
            remove_row: {
              disabled() {
                // 只能删除第三行和倒数第二行之间
                const r1 = 2
                const r2 = this.countRows() - 1
                // 总行数控制在不少于4行
                if (r2 < 4)
                  return true
                const [startRow] = this.getSelectedLast() ?? []
                if (startRow) {
                  return startRow < r1 || startRow >= r2
                }
                return true
              },
            },
            sq1: '---------',
            undo: {
              callback() {
                this.getPlugin('undoRedo').undo()
              },
            },
            redo: {
              callback() {
                this.getPlugin('undoRedo').redo()
              },
            },
          },
        },
    mergeCells: [],
    cell: [{ row: 5, col: 1, className: 'htLeft' }],
    licenseKey: 'non-commercial-and-evaluation',
  })

  // 处理输入的值，parseFloat
  hot.value.addHook('beforeChange', beforeChangeHook(() => {
    const r = hot.value?.countRows() ?? 0
    const ret = []
    if (r > 3) {
      let row = 2
      while (row < r - 1) {
        ret.push([row, '0'] as [number, string])
        row++
      }
    }
    return ret
  }))

  // 选中单元格后可以直接输入
  hot.value.addHook('afterSelectionEnd', (row, col) => {
    if (props.readonly)
      return
    if (row < 0 || col < 0)
      return
    const value = hot.value?.getSourceDataAtCell(row, col) ?? null
    hot.value?.getActiveEditor()?.beginEditing()
    hot.value?.getActiveEditor()?.setValue(value)
  })

  // 增加行后
  hot.value.addHook('afterCreateRow', () => {
    // 更新要合并单元格
    updateMergeCells()
    // 更新单元格只读或不可编辑
    updateReadonly()
    // 更新单元格的公式
    updateFormulas()
  })
  // 删除行后
  hot.value.addHook('afterRemoveRow', () => {
    // 更新要合并单元格
    updateMergeCells()
    // 更新单元格只读或不可编辑
    updateReadonly()
    // 更新单元格的公式
    updateFormulas()
  })

  // debug
  if (import.meta.env.VITE_REPORT_DEBUG === '1') {
    hot.value.addHook('afterSelection', (row, col) => {
      if (row > -1 && col > -1) {
        console.info(`[${row},${col}] ${hot.value?.getSourceDataAtCell(row, col)}`)
        document.execCommand('copy')
      }
    })
  }
}

const { isDark } = useTheme(async () => {
  if (hot.value) {
    hot.value.destroy()
    hot.value = undefined
    await nextTick()
    await bootstrap()
  }
})

async function bootstrap() {
  init()
  await loadData()
  updateMergeCells()
  updateReadonly()
  updateFormulas()
  generateHash()
}

onMounted(bootstrap)

watch(() => props.readonly, updateReadonly)

function getMergeCells() {
  const m = hot.value?.getPlugin('mergeCells')
  return (m as any).mergedCellsCollection.mergedCells
}

function getSourceData() {
  return hot.value?.getSourceData() ?? []
}
function getList() {
  const d = getSourceData()
  const r = hot.value?.countRows()
  if (r && r > 3) {
    // 数据集行在第3行到倒数第2行（含）
    const data = d.slice(2, r - 1)
    return data.map((v: any) => {
      const ret = KEYS.reduce((acc, vv, ii) => {
        acc[vv] = v[ii]
        return acc
      }, {} as any)
      ret.formId = unref(formId)
      return ret
    })
  }
  return []
}

function getSettings() {
  return {
    sourceData: getSourceData(),
    mergeCells: getMergeCells(),
    list: getList(),
    extraMapData: {
      // 实际总风量(立方米)
      ztfjSjzfl: hot.value?.getSourceDataAtCell(2, 4) ?? null,
      // 平均全压(帕)
      ztfjPjqy: hot.value?.getSourceDataAtCell(2, 5) ?? null,
    },
  }
}

async function save({ saveType, beforeSaveFn, afterSaveFn }: SaveParams) {
  const s = getSettings()
  const src = loadReportResponse.value
  const params = {
    ...src,
    ...s.extraMapData,
    reportId: REPORT_ID.COMPANY_PRIMARY_ELECTRICITY_DEVICE,
    formId: unref(formId),
    saveType,
    dataList: s.list,
    webReportData: JSON.stringify(s.sourceData),
    webReportFormat: JSON.stringify({
      mergeCells: s.mergeCells,
    }),
  }

  if (!hot.value)
    return
  // 校验表格数据类型
  const validate = useValidate(hot.value)
  const result = await validate().catch(() => {})
  hot.value.render()
  if (typeof result !== 'boolean') {
    return
  }

  // 保存前的回调
  let before = true
  if (beforeSaveFn) {
    before = await beforeSaveFn(
      REPORT_ID.COMPANY_PRIMARY_ELECTRICITY_DEVICE,
      unref(formId),
      params,
    )
  }
  if (before) {
    let responseId: number | undefined = params.id
    let after = true
    try {
      if (params.id) {
        await updateReportDataOfCompanyPrimaryElectricityDevice(params)
      }
      else {
        const { data } = await saveReportDataOfCompanyPrimaryElectricityDevice(params)
        responseId = data.id
      }
    }
    catch (e) {
      after = false
    }
    hot.value.render()
    // 保存成功后更新hash
    generateHash()
    // 保存后的回调
    after && afterSaveFn?.(
      REPORT_ID.COMPANY_PRIMARY_ELECTRICITY_DEVICE,
      unref(formId),
      params,
      responseId,
    )
  }
}

useHotUnmount(() => hot.value)

async function submitForTab(o: SaveFnParams) {
  return new Promise((resolve, reject) => {
    const s = getSettings()
    const src = loadReportResponse.value
    const params = {
      ...src,
      ...s.extraMapData,
      reportId: REPORT_ID.COMPANY_PRIMARY_ELECTRICITY_DEVICE,
      formId: unref(formId),
      // 保存
      saveType: 0,
      dataList: s.list,
      webReportData: JSON.stringify(s.sourceData),
      webReportFormat: JSON.stringify({
        mergeCells: s.mergeCells,
      }),
      ...o,
    }

    _submitForTab(params, resolve, reject)
  })
}

defineExpose({
  getSettings,
  save,
  generateHash,
  checkHash,
  submitForTab,
})
</script>

<template>
  <div class="h-full w-full">
    <div
      ref="wrapper" class="h-full w-full overflow-auto" :class="{
        'ht-theme-main-dark': isDark,
        'ht-theme-main': !isDark,
      }"
    />
  </div>
</template>
